import styles from './register.module.scss'
import React, { useState } from 'react'
import classNames from 'classnames'
import { Form, Input, Modal, message } from 'antd'
import { register, checkAccount } from '@/api/user'
import { useNavigate, useLocation } from 'react-router-dom'

import logoPath from '@/assets/img/gg-exam-logo.png'
import OtherLogin from '@/components/other-login/other-login'

const Register: React.FC = () => {
  /**
   * 变量集合 在es6中 const let 是有块级作用域的所以，最好就把变量什么放到最前面 避免变量提升引发的错误
   */
  const [form] = Form.useForm()
  const [isModalOpen, setIsModalOpen] = useState(false) // 对话框
  const [errorMsg, setErrorMsg] = useState('')
  let validationErrors: Array<ValidError> = [] // 保存失焦验证中的错误信息
  const navigate = useNavigate() // 路由跳转
  const [messageApi, contextHolder] = message.useMessage() //消息提示框
  const location = useLocation() // 路由信息
  /**
   * type
   */
  type FieldType = {
    email?: string
    phone?: string
    name?: string
    password?: string
    confirm_password?: string
  }
  type ValidError = {
    fieldName?: string
    error: string
  }
  interface subType {}

  /**
   * 错误验证数组的相关操作
   */
  const removeByFieldName = (fieldName: string) => {
    return validationErrors.filter(item => item.fieldName !== fieldName)
  }
  const addValidationErrorsNotExists = (fieldName: string, error: string) => {
    // 如果数组中不存在相同的 fieldName，则添加
    if (!validationErrors.some(item => item.fieldName === fieldName)) {
      validationErrors.push({ fieldName, error })
    }
  }

  /**
   * 注册
   */
  const _submit = async (values: subType) => {
    if (validationErrors.length > 0) {
      for (const item of validationErrors) {
        await form.validateFields([item.fieldName])
        form.setFields([{ errors: [item.error], name: item.fieldName }])
      }
      return
    }
    const res = await register(values)
    if (typeof res.message === 'object') {
      res.message = JSON.stringify(res.message)
    }

    if (res.code > 299 || res.code < 200) {
      setIsModalOpen(true)
      setErrorMsg(`${res.message}`)
      return
    }

    messageApi.open({
      type: 'success',
      content: '注册成功'
    })

    const fromPath = location.state ? location.state.from : 'home'
    setTimeout(() => {
      navigate('/login', { replace: true, state: { from: fromPath } })
    }, 500)
  }

  /**
   * 检测账号是否已经注册 手机 邮箱
   */
  const check = async (value: string, fieldName: string) => {
    try {
      // 进行异步验证
      const result = await checkAccount({ account: value })
      const text = fieldName === 'email' ? '邮箱' : '手机号'
      // 如果验证失败，添加错误信息
      if (result.code >= 400 && result.message !== '系统错误') {
        // 触发表单验证
        await form.validateFields([fieldName])
        if (typeof result.message === 'object') {
          form.setFields([{ errors: [`请输入正确的${text}格式`], name: fieldName }])
          // validationErrors.push({ fieldName, error: `请输入正确的${text}格式` })
          addValidationErrorsNotExists(fieldName, `请输入正确的${text}格式`)
        } else {
          // validationErrors.push({ fieldName, error: `${text}已经注册` })
          addValidationErrorsNotExists(fieldName, `${text}已经注册`)
          // 在验证失败时设置错误信息
          form.setFields([{ errors: [`${text}已经注册`], name: fieldName }])
        }
      } else {
        // 如果验证成功，清除之前保存的错误信息
        validationErrors = removeByFieldName(fieldName)
      }
    } catch (error) {
      console.error('验证不通过:', error)
    }
  }

  /**
   * 验证两遍密码是否一致
   */
  const validatePassword = async (value: string) => {
    const password = form.getFieldValue('password')

    if (password !== value) {
      await form.validateFields(['confirm_password'])
      form.setFields([{ errors: [`密码不一致`], name: 'confirm_password' }])
      // validationErrors.push({ fieldName: 'confirm_password', error: `密码不一致` })
      addValidationErrorsNotExists('confirm_password', `密码不一致`)
      // 在验证失败时设置错误信息
    } else {
      validationErrors = removeByFieldName('confirm_password')
    }
  }

  /**
   * 对话框相关
   */
  const handleOk = () => {
    setIsModalOpen(false)
  }
  const handleCancel = () => {
    setIsModalOpen(false)
  }

  return (
    <>
      {contextHolder}
      {/* 提示框 */}
      <Modal title="提示" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
        <p>{errorMsg}</p>
      </Modal>
      <div className={styles.box_login}>
        <div className={styles.login}>
          <div className={styles.title}>
            <div className={styles.logo}>
              <img src={logoPath} alt="GG题库" />
            </div>
            GG题库用户注册
          </div>
          {/* 表单 */}
          <Form form={form} wrapperCol={{ span: 36 }} onFinish={_submit} initialValues={{ remember: true }} autoComplete="off">
            <Form.Item<FieldType> name="email" rules={[{ required: true, message: '请输入邮箱' }]}>
              <Input placeholder="请输入邮箱" onBlur={e => check(e.target.value, 'email')} />
            </Form.Item>

            <Form.Item<FieldType> name="phone" rules={[{ required: true, message: '请输入手机号' }]}>
              <Input placeholder="请输入手机号" onBlur={e => check(e.target.value, 'phone')} />
            </Form.Item>

            <Form.Item<FieldType> name="name" rules={[{ required: true, message: '请输入昵称' }]}>
              <Input placeholder="请输入昵称" />
            </Form.Item>

            <Form.Item<FieldType>
              name="password"
              rules={[
                { required: true, message: '请输入密码' },
                { min: 6, message: '密码最少需要6位' }
              ]}
            >
              <Input placeholder="请输入密码" />
            </Form.Item>

            <Form.Item<FieldType> name="confirm_password" rules={[{ required: true, message: '请再一次输入密码' }]}>
              <Input placeholder="请确认密码" onChange={e => validatePassword(e.target.value)} />
            </Form.Item>
            <div className={classNames(styles.box_btn)}>
              <button type="submit" className={classNames(styles.btn_login)}>
                注册
              </button>
            </div>
            <OtherLogin flag={'register'} />
          </Form>
        </div>
      </div>
    </>
  )
}

export default Register
